package gw.com.android.presenter;

import android.text.TextUtils;

import com.gwtsz.android.rxbus.RxBus;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import gw.com.android.app.GTConfig;
import gw.com.android.model.ConfigUtil;
import gw.com.android.presenter.http.Https;
import gw.com.android.utils.ENV;
import gw.com.jni.library.terminal.GTSConst;
import okhttp3.Request;
import okhttp3.Response;
import www.com.library.app.Logger;

/**
 * 配置中心广告请求
 * APP内请求成功后，只请求一次
 *
 * @author jett
 * @since 2018-02-01.
 */
public class AdsConfigPresenter {

    private static final String TAG = "AdsConfigPresenter";
    private static final AdsConfigPresenter instance = new AdsConfigPresenter();

    public static final String TYPE_HOME_POP = "1";                 // 首页弹窗广告
    public static final String TYPE_HOME_BANNER = "2";              // 首页头部轮播广告
    public static final String TYPE_HOME_MIDDLE = "3";              // 首页中间广告
    public static final String TYPE_LAUNCH_PAGE = "4";              // 启动页
    public static final String TYPE_ADVER_PAGE = "5";               // 广告页
    public static final String TYPE_CREATE_ORDER_FAILED = "6";      // 市价下单失败
    public static final String TYPE_CREATE_ORDER_SUCCESS = "7";     // 市价下单成功
    public static final String TYPE_CLOSE_ORDER_SUCCESS = "8";      // 市价平仓成功
    public static final String TYPE_CLOSE_ORDER_PROFIT = "9";       // 市价平仓盈利
    public static final String TYPE_NOTICE = "10";                      // 走马灯公告
    public static final String TYPE_SHARE_QRCODE = "11";                //分享二维码
    public static final String TYPE_BEFORE_CREATE_ORDER = "15";         // 市价开仓提交前页面
    public static final String TYPE_HOME_FLOAT = "16";                  // 首页悬浮窗广告
    public static final String TYPE_HOME_BOTTOM = "17";                 // 首页底部开护栏广告词
    public static final String TYPE_ME_MENU = "19";                 // 我的菜单栏广告
    public static final String TYPE_HOME_OPEN_REAL = "23";              // 首页真实开户副标题
    public static final String TYPE_HOME_OPEN_DEMO = "22";              // 首页模拟开户副标题
    public static final String TYPE_NOVICE_WELFARE = "24";              // 新手福利小弹窗
    public static final String TYPE_TAB_TRADE = "25";               // 首页交易tab的图标

    public static final String TYPE_NEW_GUIDE_AND_ABOUT_US = "86";       //新手指南-关于恒信

    public static final String TYPE_NEW_WELFARE_TOTAL = "87";       //新手福利广告位条目汇总

    public static final String TYPE_HOME_OPEN_REAL_DEMO = "88"; // 首页真实-模拟开户副标题

    // 新手福利的N张图，
    public static final String TYPE_NEW_WELFARE_TITLE = "80";//新手福利标题NewWelfare

    private static final int STATE_UNLOAD = 0;
    private static final int STATE_LOADING = 1;
    private static final int STATE_COMPLETED = 2;

    private int state = STATE_UNLOAD;
    private Map<String, AdsData> mGuestAds;
    private Map<String, AdsData> mDemoAds;
    private Map<String, AdsData> mRealAds;
    private Map<String, AdsData> mActiveAds;
    private Map<String, AdsData> mNotActiveAds;

    private AdsConfigPresenter() {
    }

    public static AdsConfigPresenter getInstance() {
        return instance;
    }

    /**
     * 游客跟模拟，直接根据广告类型取对应的广告位
     * <p>
     * 真实账号需先判断，该账号是否已激活，
     * 如无激活信息，取真实广告
     * 如有激活信息，取对应是否激活的广告，若取的广告为空则再取真实广告
     */
    public AdsData getAd(String type) {
        int accountType = GTConfig.instance().getAccountType();
        if (accountType != GTConfig.ACC_TYPE_REAL) {
            return getAd(type, accountType);
        } else {
            int accountActive = GTConfig.instance().isAccountActive();
            if (accountActive != 0) {
                int activeType = accountActive > 0 ? GTConfig.ACC_TYPE_ACTIVE : GTConfig.ACC_TYPE_NOTACTIVE;
                AdsData ad = getAd(type, activeType);
                if (ad == null) {
                    ad = getAd(type, accountType);
                }
                return ad;
            } else {
                return getAd(type, accountType);
            }
        }
    }

    private AdsData getAd(String type, int accountType) {
        Map<String, AdsData> ads = getAllAds(accountType);
        if (ads != null) {
            return ads.get(type);
        }
        return null;
    }

    public Map<String, AdsData> getAllAds(int accountType) {
        if (accountType == GTConfig.ACC_TYPE_GUEST) {
            return mGuestAds;
        } else if (accountType == GTConfig.ACC_TYPE_REAL) {
            return mRealAds;
        } else if (accountType == GTConfig.ACC_TYPE_DEMO) {
            return mDemoAds;
        } else if (accountType == GTConfig.ACC_TYPE_ACTIVE) {
            return mActiveAds;
        } else if (accountType == GTConfig.ACC_TYPE_NOTACTIVE) {
            return mNotActiveAds;
        }
        return null;
    }

    public void loadAds() {
        if (state != STATE_UNLOAD) {
            Logger.i(TAG, "ads is loading or completed.");
            return;
        }
        state = STATE_LOADING;
        Logger.i(TAG, "start request config centre ads..");
        new Https(getAdsUrl()).responseOnUiThread(false).get(new Https.ResponseCallback<String>() {
            @Override
            public void onSuccess(Request request, Response response, String result, int code) {
                Logger.i(TAG, "config centre ads request completed");
                try {
                    parseAds(result);
                    state = STATE_COMPLETED;
                } catch (JSONException e) {
                    state = STATE_UNLOAD;
                    Logger.e(TAG, e);
                }
            }

            @Override
            public void onFailure(Request request, IOException e) {
                state = STATE_UNLOAD;
                Logger.e(TAG, e);
            }
        });
    }

    public boolean isCompleted() {
        return state == STATE_COMPLETED;
    }

    private void parseAds(String result) throws JSONException {
        if (TextUtils.isEmpty(result)) {
            Logger.i(TAG, "ads result is empty");
            return;
        }
        JSONObject adJson = new JSONObject(result);
        JSONObject dataJson = adJson.optJSONObject("data");
        if (dataJson == null || dataJson.length() <= 0) {
            Logger.i(TAG, "ads data is empty");
            return;
        }
        Logger.i(TAG, "load successful");

        JSONObject guestJson = dataJson.optJSONObject("guest");
        JSONObject demoJson = dataJson.optJSONObject("simulation");
        JSONObject realJson = dataJson.optJSONObject("real");
        JSONObject activeJson = dataJson.optJSONObject("realA");
        JSONObject notActiveJson = dataJson.optJSONObject("realN");
        mDemoAds = parseAdsType(demoJson);
        mGuestAds = parseAdsType(guestJson);
        mRealAds = parseAdsType(realJson);
        mActiveAds = parseAdsType(activeJson);
        mNotActiveAds = parseAdsType(notActiveJson);

        AdverPagePresenter.getInstance().preload();
        NoviceWelfarePresenter.getInstance().onAdsLoadCompleted();
        RxBus.getInstance().post(GTSConst.REPLY_RFRESH_ADS, "");
    }

    private Map<String, AdsData> parseAdsType(JSONObject dataJson) {
        if (dataJson == null) {
            return null;
        }
        Map<String, AdsData> map = new HashMap<>();
        Iterator<String> keys = dataJson.keys();
        while (keys.hasNext()) {
            String next = keys.next();
            JSONObject detailJson = dataJson.optJSONObject(next);
            AdsData adsData = parseAdDetail(detailJson);
            map.put(next, adsData);
        }
        return map;
    }

    private AdsData parseAdDetail(JSONObject detailJson) {
        if (detailJson == null) {
            return null;
        }
        AdsData data = new AdsData();
        data.positionRemark = detailJson.optString("positionRemark");
        data.remark = detailJson.optString("remark");
        data.title = detailJson.optString("title");
        data.type = detailJson.optString("type");
        data.version = detailJson.optString("version");
        data.content = detailJson.optString("content");
        data.displayPos = detailJson.optString("displayPos");
        data.adType = detailJson.optString("adType");
        data.customerType = detailJson.optString("customerType");
        data.clientType = detailJson.optString("clientType");
        data.linkUrl = detailJson.optString("linkUrl");
        data.name = detailJson.optString("name");
        data.id = detailJson.optString("id");
        data.category = detailJson.optString("category");
        JSONArray adPics = detailJson.optJSONArray("adPics");
        if (adPics != null && adPics.length() > 0) {
            data.adPics = new ArrayList<>();
            for (int i = 0; i < adPics.length(); i++) {
                JSONObject json = adPics.optJSONObject(i);
                if (json != null) {
                    AdsData.PicData picData = data.newPicData();
                    picData.link = json.optString("link");
                    picData.id = json.optString("id");
                    picData.sort = json.optString("sort");
                    picData.title = json.optString("title");
                    picData.url = json.optString("url");
                    data.adPics.add(picData);
                }
            }
        }
        return data;
    }

    private String getAdsUrl() {
        // http://192.168.35.95:8080/2/android/main/ad/latest/manifest.json
        String host = ENV.isUat() ? "http://192.168.35.95:8080/" : "https://appcfg.hx9999.com/";
        String url = host + "2/@platform@/@channelName@/ad/latest/manifest.json";
        url = ConfigUtil.getDealStrUrl(url);
        if (url.contains("umeng")) {
            url = url.replace("umeng", "main");
        }
        Logger.i(TAG, "getAdsUrl = " + url);
        return url;
    }

}
